import Ember from 'ember';

const { Mixin, run, computed, RSVP: { resolve } } = Ember;

/**
 A mixin for infinite scrolls.

 @class EmberCliInfiniteScroll.Mixin.InfiniteScroll
 @extends Ember.Mixin
 */

export default Mixin.create({
  service_PageConstrut:Ember.inject.service("page-constructure"),
  infiniteCallback:null,//预存callback接口
  /**
   True if a request has been initiated but not resolved.
   @property infiniteQuerying
   @default false
   */
  infiniteQuerying: false,
  //循环被查询次数
  _cycleCount: 0,
  //是否滚动可用
  infiniteScrollAvailable: true,
  //底部距离判断阀值
  triggerDistance: 10,
  //是否具备触发条件
  aboveTheTrigger: false,
  //是否有更多内容
  hasMoreContent: true,
  //页码
  "page[number]": 1,
  //每页数据量
  "page[size]": 20,
  //页码参数
  infiniteIncrementProperty: 'page[number]',
  //每页数据参数
  infiniteIncrementBy: 'page[size]',
  //返回值中的总页数
  totalPagesResKey: "meta.totalPage",
  //iscroll容器id
  infiniteContainerName: 'iscroll',
  //查询的model
  infiniteContentPropertyName: 'model',
  infiniteModelName: '',
  //拼接的查询参数
  _fullQueryParams: computed('infiniteIncrementBy', 'infiniteIncrementProperty', 'infiniteQueryParams', function() {
    let defaultQueryParams = [this.get('infiniteIncrementBy'), this.get('infiniteIncrementProperty')];
    let infiniteQueryParams = this.get('infiniteQueryParams');
    return defaultQueryParams.concat(infiniteQueryParams);
  }),
  infiniteQueryParams: [],
  getContainerDom: function(){
    var selector = "#" + this.get("infiniteContainerName") + " .wrapperInner";
    return $(selector);
  },

  /**
   Does what's needed for the infinite scroll.
   - sets `infiniteQuerying` to `true`
   - if passed `modelName`, sets `infiniteModelName`
   - if passed `params`, sets `infiniteQueryParams`
   - calls `beforeInfiniteQuery`
   - calls `infiniteQuery`
   then:
   - calls `afterInfiniteQuery`
   - calls `_updateInfiniteProperties`
   - sets ` infiniteQuerying` to `false`

   @method performInfinite
   @param modelName { String } the model to be queried
   @param params { Object } params to use in the query
   @returns { Promise } the records
   */

  infiniteQuery(modelName, params,callback) {
    var _self = this;
    //如果有model名，说明是第一次查询，重置参数
    console.log("infiniteQuery is in,modelName:" + modelName);
    if(modelName&&modelName.trim()!=="undefined") {
      console.log("need reset");
      //首先对滚动屏实施一个遮罩加载的效果
      this._showLoading();
      this.resetInfinite();
      this.set('infiniteModelName', modelName);
    }
    console.log("infiniteQuerying:" + this.get('infiniteQuerying') + " and infiniteScrollAvailable:" + this.get("infiniteScrollAvailable"));
    if (this.get('infiniteQuerying') || !this.get('infiniteScrollAvailable')) {
      this._hideLoading();
      return resolve([]);
    }
    this.set('infiniteQuerying', true);
    if(params) {
      let paramsToSet = Object.keys(params);
      this.set('infiniteQueryParams', paramsToSet);
      this.setProperties(params);
    }
    let infiniteModelName = this.get('infiniteModelName');
    let fullQueryParams = this.get('_fullQueryParams');
    params = this.getProperties(fullQueryParams);
    this.beforeInfiniteQuery(params);
    let newRecords = this.infiniteDataQuery(infiniteModelName, params)
    .then(records => {
      let totalPages = records.get(_self.get('totalPagesResKey'));
      let returnedContentLength = records.get('length');
      let recordsArray = records.toArray();
      this.afterInfiniteQuery(recordsArray);
      _self._hideLoading();
      this._updateInfiniteProperties(returnedContentLength,totalPages);
      this.set('infiniteQuerying', false);
      if(callback){
        this.infiniteCallback = callback;
        callback(recordsArray);
      }else{
        //执行预存的回调
        if(this.infiniteCallback){
          this.infiniteCallback();
        }
      }
      return recordsArray;
    });

    return newRecords;
  },

  _showLoading: function(){
    var containerDom = this.getContainerDom();
    var loadDom = $("<div id='loadingDiv'><img src='assets/images/loading.gif'/></div>");
    containerDom.parent().append(loadDom);
    containerDom.hide();
  },
  _hideLoading: function(){
    var containerDom = this.getContainerDom();
    var loadDom = $("#loadingDiv");
    containerDom.show();
    loadDom.remove();
  },
  /**
   Called immediately before the infinite query starts.

   @method beforeInfiniteQuery
   @param params { Object } the params that will be used in the query
   */

  beforeInfiniteQuery: Ember.K,

  /**
   The query that will be used.

   @method infiniteQuery
   @param modelName { String } the name of the model
   @param params { Object } the params that will be used in the query
   @return { Promise } the records
   */

  infiniteDataQuery(modelName, params={}) {
    return this.get('store').query(modelName, params);
  },

  /**
   Record processing or anything else that needs to happen with the returned
   records.

   @method afterInfiniteQuery
   @param  newRecords { Object } the records returned in this cycle
   */

  afterInfiniteQuery(newRecords) {
    var _self = this;
    let contentPropertyName = this.get('infiniteContentPropertyName');
    let model = this.get(contentPropertyName);
    if (!model) {
      model = new Ember.A();
    }
    model.addObjects(newRecords);
    this.set(contentPropertyName,model);
    console.log("model len is:" + model.get("length"));
    //iscroll初始化
    var scroller = this.get("_scroller");
    //如果当前屏幕还未初始化，则不处理
    if(!scroller){
      return;
    }
    console.log("scroller is:",scroller);
    Ember.run.later(function(){
      _self._refreshScroller();
    },100);
  },

  /**
   Calls `_updateInfiniteCount` and `updateInfiniteAvailable`.

   @method _updateScrollProperties
   @param addedLength { Number } the incremental length of the model
   @private
   */

  _updateInfiniteProperties(addedLength,totalPages) {
    this._updateInfiniteCount(addedLength);
    this.updateHasMoreContent(addedLength,totalPages);
    this.incrementProperty('_cycleCount');
  },

  /**
   Increments a property after the infinite scroll is finished.

   @method _updateInfiniteCount
   @param addedLength { Number } the incremental length of the model
   @private
   */

  _updateInfiniteCount(addedLength) {
    let incrementProperty = this.get('infiniteIncrementProperty');
    let increment = this.get(incrementProperty) + 1;
    this.set(incrementProperty,increment);
    // this.incrementProperty(incrementProperty, addedLength);
  },

  /**
   Determines whether the infinite scroll should continue after it finishes.

   @method updateHasMoreContent
   @param addedLength { Number } the incremental length of the model
   */

  updateHasMoreContent(addedLength,totalPages) {
    let infiniteIncrement = this.get("infiniteIncrementProperty");
    let curPageNum = this.get(infiniteIncrement);
    let hasMoreContent = curPageNum <= totalPages;
    this.set('hasMoreContent', hasMoreContent);
    console.log("need hasMoreContent:" + hasMoreContent);
    this.set('infiniteScrollAvailable', hasMoreContent);
  },
  //查询重置
  resetInfinite() {
    let {
      infiniteIncrementProperty,
      infiniteContentPropertyName
    } = this.getProperties('infiniteContentPropertyName', 'infiniteIncrementProperty');
    if(this.get(infiniteContentPropertyName)){
      var list = this.get(infiniteContentPropertyName);
      console.log("list get",list);
      if(list){
        list.clear();
      }
    }
    this.set("_cycleCount",0);
    this.set(infiniteIncrementProperty, 1);
    this.set('hasMoreContent', true);
    this.set('infiniteScrollAvailable', true);
    this._initIscroll();
  },

  //检查是否达到底部
  _listenerFired() {
    var containerDom = this.getContainerDom();
    let scroller = this.get('_scroller'),
        triggerDistance = this.get('triggerDistance'),
        previousAboveTheTrigger = this.get('aboveTheTrigger');

    let offsetFromTop = containerDom.offset().top,
        scrollContainerPosition =  parseInt(scroller.y) * -1,
        scrollContainerHeight = containerDom.height()-560;

    let heightOffset = scrollContainerPosition + triggerDistance;
    let mayLoadContent = ( heightOffset >= scrollContainerHeight );
    console.log("heightOffset:" + heightOffset + " and scrollContainerHeight:" +
      scrollContainerHeight + " scrollContainerPosition:" + scrollContainerPosition);
    if (mayLoadContent) {
      this.infiniteQuery();
    }
  },
  //初始化iscroll
  _initIscroll: function(){
    var _self = this;
    var scroller = this.get("_scroller");
    if(scroller){
      console.log("need destroy first");
      scroller.destroy();
    }
    var containerName = "#" + this.get("infiniteContainerName");
    console.log("containerName is:" + containerName);
    Ember.run.later(function(){
      console.log("rende,Container len:",Ember.$(containerName).length);
      document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
      scroller = new IScroll(containerName, {
        mouseWheel: false,//侦听鼠标滚轮事件
        scrollX : false, //是否水平滚动
  			scrollY : true, //是否垂直滚动
  			startY : 20, //滚动垂直初始位置
  			bounce : true, //是否超过实际位置反弹
  			momentum : true, //动量效果，拖动惯性
  			freeScroll : false,
  			useTransform : true, //是否使用CSS形变
  			useTransition : true, //是否使用CSS变换
  			checkDOMChanges : false, //是否自动检测内容变化
  			fixedScrollbar : true, //对andriod的fixed
  			scrollbars : true, //是否隐藏滚动条
  			fadeScrollbar : false, //滚动条是否渐隐渐显
  			scrollbarClass : '', //自定义滚动条的样式名
      });
      scroller.on("scrollEnd",function () {
        console.log('scroll end in');
        _self._listenerFired();
      });
      _self.set("_scroller",scroller);
      _self._refreshScroller();
    },500);
  },
  _refreshScroller:function() {
    var scroller = this.get("_scroller");
    scroller.refresh();
    //需要调整滚动高度值
    scroller.maxScrollY = scroller.maxScrollY - 90;
  },
  actions: {
    //从组件可以接到didRender事件
    didRender() {
      //接收到渲染事件后重新初始化iscroll
      console.log("didRender in,this.infiniteContainerName:" + this.get("infiniteContainerName"));
      // this._initIscroll();
    },
    didInsertElement() {
      //接收到insert渲染事件后初始化iscroll
      console.log("didInsertElement in,this.infiniteContainerName:" + this.get("infiniteContainerName"));
      this._initIscroll();
    },
    //激活显示页面的事件处理,需要屏幕刷新
    switchShowAction(){
      var _self = this;
      console.log("switchShowAction in");
      var scroller = this.get("_scroller");
      if(scroller){
        console.log("do refresh");
        Ember.run.later(function(){
          _self._refreshScroller();
        },100);
      }
    }
  }
});
